using DBUtil.SqlSegment;

namespace DBUtil.Provider.MySql.SqlSegment
{
    /// <summary>
    /// 数据库字符串运算符
    /// </summary>
    public class MySqlStringSqlSegment : StringSqlSegment
    {
        public MySqlStringSqlSegment(DBAccess db) : base(db)
        {
        }

        public override string GetLength(string sqlSeg, bool null2Zero = false)
        {
            if (null2Zero) return $"length(ifnull({sqlSeg},''))";
            else return $"length({sqlSeg})";
        }
        public override string Trim(string sqlSeg) => $"trim({sqlSeg})";
        public override string LeftTrim(string sqlSeg) => $"ltrim({sqlSeg})";
        public override string RightTrim(string sqlSeg) => $"rtrim({sqlSeg})";
        public override string Upper(string sqlSeg) => $"upper({sqlSeg})";
        public override string Lower(string sqlSeg) => $"lower({sqlSeg})";
        public override string ReplaceAll(string inputSqlSeg, string oldStrSqlSeg, string newStrSqlSeg) => $"replace({inputSqlSeg},{oldStrSqlSeg},{newStrSqlSeg})";
        public override string SplitFirst(string inputSqlSeg, string patternSqlSeg) => $"substring_index({inputSqlSeg}, {patternSqlSeg}, 1)";
        public override string SplitLast(string inputSqlSeg, string patternSqlSeg) => $"substring_index({inputSqlSeg}, {patternSqlSeg}, -1)";
        //为什么用 concat_ws 而不是 concat?
        //因为: concat(null,a) => null, 而 concat_ws('',null,'a') => 'a'
        // c#中 null+'a' => 'a' 与 concat_ws 行为一致
        public override string Add(string inputSqlSeg, string input2SqlSeg) => $"concat_ws('',{inputSqlSeg},{input2SqlSeg})";
        public override string SubString(string sqlSeg, int start, int len) => $"substr({sqlSeg},{start + 1},{len})";

        /// <summary>
        /// 按照 pattern 分割后,如果有多个项,则移除第一个<br />
        /// 应用场景: 参照: <seealso cref="SplitSkipLastIfMultiple"/><br/>
        /// 示例:<br/>
        /// <list type="bullet">
        /// <item>"xiaoming@hong@localhost" => "hong@localhost"</item>
        /// <item>"xiaoming@hong" => "hong"</item>
        /// <item>"xiaoming" => "xiaoming"</item>
        /// </list>
        /// </summary>
        public string SplitSkipFirstIfMultiple(string inputSqlSeg, string patternSqlSeg) => $"substring({inputSqlSeg},instr({inputSqlSeg},{patternSqlSeg})+1)";

        /// <summary>
        /// 按照 pattern 分割后,如果有多个项,则移除最后一个<br />
        /// 应用场景1: 去除文件后缀名<br />
        /// 应用场景2: 去除user()函数后的ip<br />
        /// <list type="bullet">
        /// <item>"xiaoming@hong@localhost" => "xiaoming@hong"</item>
        /// <item>"xiaoming@hong" => "xiaoming"</item>
        /// <item>"xiaoming" => "xiaoming"</item>
        /// </list>
        /// </summary>
        public string SplitSkipLastIfMultiple(string inputSqlSeg, string patternSqlSeg) => $"reverse(substring(reverse({inputSqlSeg}),instr(reverse({inputSqlSeg}),{patternSqlSeg})+1))";

        public override string IndexOf(string inputSqlSeg, string patternSqlSeg, bool ignoreCase = true)
        {
            return $"(locate({patternSqlSeg},{(ignoreCase == false ? "binary " : "")}{inputSqlSeg})-1)";
        }

        public override string IsNullOrEmpty(string inputSqlSeg)
        {
            return $"({inputSqlSeg} is null or length({inputSqlSeg}) = 0)";
        }
        public override string IsNullOrWhiteSpace(string inputSqlSeg)
        {
            return $"({inputSqlSeg} is null or length(trim({inputSqlSeg})) = 0)";
        }
    }
}
